In [1]:
# Import libraries and modules
import numpy as np
import Synthesis as synt
import time
import Utils as ut
import TestCase as tc
from copy import deepcopy
from qiskit_textbook.tools import array_to_latex
In [2]:
# Testcase preparation
U = ut.generateRandomU(nq=4, nc=30) # Generate random matrix
#U = tc.u # or Use already manually generated matrises in TestCase.py
In [3]:
# Show input matrix
ut.matrix_to_latex(U) 
Out[3]:
$\displaystyle \left[\begin{array}{cccccccccccccccc}\frac{\sqrt{2} \omega}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{\sqrt{2} \omega^{2}}{2} & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1\\- \frac{\omega^{2}}{2} & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{\omega^{3}}{2} & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & \frac{\sqrt{2} \omega^{2}}{2} & 0 & 0 & 0 & - \frac{\sqrt{2} \omega^{3}}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\- \frac{1}{2} & 0 & \frac{\sqrt{2} \omega^{2}}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{\omega}{2} & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & 0 & - \frac{\sqrt{2}}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0 & \frac{\omega^{2}}{2} & 0 & 0 & 0 & 0 & \frac{1}{2} & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & - \frac{\sqrt{2} \omega^{2}}{2} & 0 & - \frac{1}{2} & 0 & 0 & 0 & 0 & \frac{\omega^{2}}{2} & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \omega & 0 & 0 & 0\\0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{\sqrt{2} \omega}{2} & 0 & 0 & 0 & 0 & - \frac{\sqrt{2} \omega^{3}}{2} & 0 & 0\\0 & \frac{\omega^{2}}{2} & 0 & 0 & 0 & \frac{\omega^{3}}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & - \frac{\sqrt{2} \omega^{3}}{2} & 0\\0 & - \frac{\omega^{3}}{2} & 0 & 0 & 0 & \frac{1}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \frac{\sqrt{2}}{2} & 0\end{array}\right]$
In [4]:
# Check if the matrix is unitary (if so return True)
ut.checkUnitarity(U)
Out[4]:
True
In [5]:
# Pass the matrix to synthesis function and call it, then save the return values
# The main return value is Clifford+T Circuit saved in cliffordTCirc variable
# The sceond return value is a higher level circuit made up of only controlled gates, saved in mcgCirc variable
# The third return value is high level components including only 2 level matrises only, saved in HLCs2 variable
# The last return value is high level components including both 2 and 1 level matrises, saved in HLCs12 variable
start_time = time.time() 
cliffordTCirc, mcgCirc, HLCs2, HLCs12 = synt.syntCliffordTCircuit(deepcopy(U))
exe_time = time.time() - start_time # measure execution time
In [6]:
# Show high level componets, 1 and 2 level matrises
HLCs12
Out[6]:
$\displaystyle T_{[3,7]}^{6} H_{[3,7]} T_{[1,3]}^{5} H_{[1,3]} \omega_{[1]} T_{[15,16]}^{5} H_{[15,16]} H_{[6,15]} X_{[2,6]} \omega_{[2]}^{2} X_{[3,7]} X_{[4,5]} H_{[5,8]} X_{[6,15]} \omega_{[6]}^{7} T_{[9,10]}^{6} H_{[9,10]} X_{[7,9]} T_{[10,14]}^{7} H_{[10,14]} X_{[9,14]} \omega_{[9]}^{2} X_{[10,12]} X_{[12,14]} \omega_{[12]}^{6} \omega_{[13]} X_{[15,16]} \omega_{[15]}^{7}$
In [7]:
# Show high level matrises, only 2 level matrises(1 levels converted into 2 levels)
HLCs2
Out[7]:
$\displaystyle T_{[3,7]}^{6} H_{[3,7]} T_{[1,3]}^{5} H_{[1,3]} X_{[1,2]} T_{[1,2]} X_{[1,2]} T_{[15,16]}^{5} H_{[15,16]} H_{[6,15]} X_{[2,6]} T_{[1,2]}^{2} X_{[3,7]} X_{[4,5]} H_{[5,8]} X_{[6,15]} T_{[1,6]}^{7} T_{[9,10]}^{6} H_{[9,10]} X_{[7,9]} T_{[10,14]}^{7} H_{[10,14]} X_{[9,14]} T_{[1,9]}^{2} X_{[10,12]} X_{[12,14]} T_{[1,12]}^{6} T_{[1,13]} X_{[15,16]} T_{[1,15]}^{7}$
In [8]:
# Show the circuit(made of only controlled gates)
mcgCirc.draw()
Out[8]:
In [9]:
# Evaluate mcg circuit
result = ut.assess(U, mcgCirc)[0]

# Show the result (True if the circuit is correct)
result
Out[9]:
True
In [10]:
# show the circuit(made of only Clifford+T gates)
cliffordTCirc.draw()
Out[10]:
In [11]:
# Evaluate Clifford+T circuit
# Uin is the input matrix (in numerical form)
# Uout is the actuall matrix of generated circuit (in numerical form)
result1,Uin,Uout = ut.assess(U, cliffordTCirc)

# Show the result (True if the circuit is correct)
result1
Out[11]:
True
In [12]:
# Show input matrix
array_to_latex(Uin)
$\displaystyle \begin{bmatrix} \tfrac{1}{2}(1 + i) & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -\tfrac{1}{\sqrt{2}}i & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ -\tfrac{1}{2}i & 0 & \tfrac{1}{\sqrt{2}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{8}}(1 - i) & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & \tfrac{1}{\sqrt{2}}i & 0 & 0 & 0 & \tfrac{1}{2}(1 - i) & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ -\tfrac{1}{2} & 0 & \tfrac{1}{\sqrt{2}}i & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{8}}(-1 - i) & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 & 0 & -\tfrac{1}{\sqrt{2}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 & \tfrac{1}{2}i & 0 & 0 & 0 & 0 & \tfrac{1}{2} & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & -\tfrac{1}{\sqrt{2}}i & 0 & -\tfrac{1}{2} & 0 & 0 & 0 & 0 & \tfrac{1}{2}i & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}}(1 + i) & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{2}(-1 - i) & 0 & 0 & 0 & 0 & \tfrac{1}{2}(1 - i) & 0 & 0 \\ 0 & \tfrac{1}{2}i & 0 & 0 & 0 & \tfrac{1}{\sqrt{8}}(-1 + i) & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{2}(1 - i) & 0 \\ 0 & \tfrac{1}{\sqrt{8}}(1 - i) & 0 & 0 & 0 & \tfrac{1}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 \\ \end{bmatrix} $$ $
In [13]:
# Show the actuall matrix of generated circuit 
# Now compare Uin and Uout visually
array_to_latex(Uout)
$\displaystyle \begin{bmatrix} \tfrac{1}{2}(1 + i) & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & -\tfrac{1}{\sqrt{2}}i & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 \\ -\tfrac{1}{2}i & 0 & \tfrac{1}{\sqrt{2}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{8}}(1 - i) & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & \tfrac{1}{\sqrt{2}}i & 0 & 0 & 0 & \tfrac{1}{2}(1 - i) & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ -\tfrac{1}{2} & 0 & \tfrac{1}{\sqrt{2}}i & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{8}}(-1 - i) & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 & 0 & -\tfrac{1}{\sqrt{2}} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 & \tfrac{1}{2}i & 0 & 0 & 0 & 0 & \tfrac{1}{2} & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & -\tfrac{1}{\sqrt{2}}i & 0 & -\tfrac{1}{2} & 0 & 0 & 0 & 0 & \tfrac{1}{2}i & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 1 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}}(1 + i) & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{2}(-1 - i) & 0 & 0 & 0 & 0 & \tfrac{1}{2}(1 - i) & 0 & 0 \\ 0 & \tfrac{1}{2}i & 0 & 0 & 0 & \tfrac{1}{\sqrt{8}}(-1 + i) & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{2}(1 - i) & 0 \\ 0 & \tfrac{1}{\sqrt{8}}(1 - i) & 0 & 0 & 0 & \tfrac{1}{2} & 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 & \tfrac{1}{\sqrt{2}} & 0 \\ \end{bmatrix} $$ $
In [14]:
# Compare 
# Uin == Uout
In [15]:
# number of clifford+T gates
len(cliffordTCirc.data)
Out[15]:
5906
In [16]:
# synthesis execuation time(in seconds)
print(exe_time,'s')
14.49391484260559 s
In [ ]: